package com.jspxcms.plug.service.impl;

import com.jspxcms.common.orm.Limitable;
import com.jspxcms.common.orm.RowSide;
import com.jspxcms.common.orm.SearchFilter;
import com.jspxcms.core.domain.Site;
import com.jspxcms.core.listener.SiteDeleteListener;
import com.jspxcms.core.service.SiteService;
import com.jspxcms.plug.domain.PlugDisease;
import com.jspxcms.plug.domain.PlugDoctor;
import com.jspxcms.plug.domain.PlugDoctorDisease;
import com.jspxcms.plug.domain.PlugHospitalDepartment;
import com.jspxcms.plug.repository.PlugDoctorDao;
import com.jspxcms.plug.repository.PlugDoctorDiseaseDao;
import com.jspxcms.plug.service.PlugDoctorService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

@Service
@Transactional(readOnly = true)
public class PlugDoctorServiceImpl implements PlugDoctorService {
    public Page<PlugDoctor> findAll(Integer siteId, Map<String, String[]> params,
                                    Pageable pageable) {
        return dao.findAll(spec(params), pageable);
    }

    public RowSide<PlugDoctor> findSide(Integer siteId,
                                        Map<String, String[]> params, PlugDoctor bean, Integer position,
                                        Sort sort) {
        if (position == null) {
            return new RowSide<PlugDoctor>();
        }
        Limitable limit = RowSide.limitable(position, sort);
        List<PlugDoctor> list = dao.findAll(spec(params), limit);
        return RowSide.create(list, bean);
    }

    private Specification<PlugDoctor> spec(
            Map<String, String[]> params) {
        Collection<SearchFilter> filters = SearchFilter.parse(params).values();
        final Specification<PlugDoctor> fsp = SearchFilter.spec(filters,
                PlugDoctor.class);
        Specification<PlugDoctor> sp = new Specification<PlugDoctor>() {
            public Predicate toPredicate(Root<PlugDoctor> root,
                                         CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate pred = fsp.toPredicate(root, query, cb);

                return pred;
            }
        };
        return sp;
    }

    public List<PlugDoctor> findList(Integer[] siteId, Limitable limitable) {
        return dao.getList(siteId, limitable);
    }

    @Override
    public HashMap<PlugDisease, List<PlugDoctor>> findByDepartmentId(Integer departmentId) {
        List rows = dao.findByDepartmentId(departmentId);
        if (rows != null) {
            HashMap<PlugDisease, List<PlugDoctor>> map = new HashMap<PlugDisease, List<PlugDoctor>>();
            for (Object tmp : rows) {
                Object[] row = (Object[]) tmp;
                PlugDisease disease = new PlugDisease();
                disease.setId(Integer.parseInt(row[6].toString()));
                disease.setfDiseaseName(row[7].toString());

                if (!map.containsKey(disease)) {
                    map.put(disease, new ArrayList<PlugDoctor>());
                }

                PlugDoctor doctor = new PlugDoctor();
                doctor.setId(Integer.parseInt(row[0].toString()));
                doctor.setfDoctorName(row[1].toString());
                map.get(disease).add(doctor);
            }
            return map;
        }
        return null;
    }

    @Override
    public List<PlugDoctor> findOtherDoctors(Integer departmentId,Integer doctorId) {
        return dao.findOtherDoctors(departmentId,doctorId);

    }

    public PlugDoctor get(Integer id) {
        return dao.findOne(id);
    }

    @Transactional
    public PlugDoctor save(PlugDoctor bean, String[] diseases) {
        bean = dao.save(bean);
        if (diseases != null) {
            ArrayList<Integer> doctors = new ArrayList<Integer>();
            doctors.add(bean.getId());
            doctorDiseaseDao.deleteByDoctorIds(doctors);
            for (String disease : diseases) {
                PlugDoctorDisease doctorDisease = new PlugDoctorDisease();
                doctorDisease.setfDiseaseId(Integer.parseInt(disease));
                doctorDisease.setfDoctorId(bean.getId());
                doctorDiseaseDao.save(doctorDisease);
            }
        }
        return bean;
    }

    @Transactional
    public PlugDoctor update(PlugDoctor bean, String[] diseases) {
        bean = dao.save(bean);
        if (diseases != null) {
            ArrayList<Integer> doctors = new ArrayList<Integer>();
            doctors.add(bean.getId());
            doctorDiseaseDao.deleteByDoctorIds(doctors);
            for (String disease : diseases) {
                PlugDoctorDisease doctorDisease = new PlugDoctorDisease();
                doctorDisease.setfDiseaseId(Integer.parseInt(disease));
                doctorDisease.setfDoctorId(bean.getId());
                doctorDiseaseDao.save(doctorDisease);
            }
        }
        return bean;
    }

    @Transactional
    public PlugDoctor delete(Integer id) {
        PlugDoctor entity = dao.findOne(id);
        dao.delete(entity);
        return entity;
    }

    @Transactional
    public PlugDoctor[] delete(Integer[] ids) {
        PlugDoctor[] beans = new PlugDoctor[ids.length];
        for (int i = 0; i < ids.length; i++) {
            beans[i] = delete(ids[i]);
        }
        return beans;
    }


    @Autowired
    private PlugDoctorDiseaseDao doctorDiseaseDao;

    @Autowired
    private PlugDoctorDao dao;


}
